/**
 * 
 */
package org.t2.game.server.module.bag.service;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.gaming.ruler.lifecycle.Lifecycle;
import org.gaming.ruler.schedule.LoopingTask;
import org.gaming.service.repository.IRepository;
import org.gaming.service.repository.Repository;
import org.gaming.service.service.jvm.PlayerOneToOneService;
import org.gaming.tool.ConsoleUtil;
import org.gaming.tool.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.t2.game.server.foundation.starting.ApplicationSettings;
import org.t2.game.server.module.backstage.BackstagePoster;
import org.t2.game.server.module.bag.model.Bag;
import org.t2.game.server.module.bag.model.CheatLog;

import jakarta.annotation.PostConstruct;
import sh.t2.share.apiutil.GameApi;
import sh.t2.share.module.bag.CheatData;
import sh.t2.share.module.bag.CheatTable;

/**
 * 
 */
@Service
public class BagService extends PlayerOneToOneService<Bag> implements Lifecycle {

	@Autowired
	private ApplicationSettings applicationSettings;
	@Autowired
	private BackstagePoster backstagePoster;
	
	private Queue<CheatLog> cheatQueue = new ConcurrentLinkedQueue<>();
	
	@Override
	protected Bag createWhenNull(long playerId) {
		return new Bag();
	}

	public void addCheat(CheatLog cheatLog) {
		cheatQueue.add(cheatLog);
		IRepository<CheatLog> logRepository = Repository.get(CheatLog.class);
		logRepository.insert(cheatLog);
	}
	
	@LoopingTask(name = "CheatTimer-后台数据上报", spaceTime = DateTimeUtil.ONE_SECOND_MILLIS * 30, execGroup = 2)
	private void runInSchedule() {
		save(false);
	}

	@Override
	public void stop() throws Exception {
		save(true);
	}
	
	private void save(boolean all) {
		if (cheatQueue.isEmpty()) {
			return;
		}
		CheatLog cheatLog = cheatQueue.poll();
		CheatTable cheatTable = new CheatTable();
		cheatTable.setServerId(applicationSettings.getGameServerId());
		
		int batchNum = 0;
		while(cheatLog != null) {
			CheatData cheatData = new CheatData();
			cheatData.setPlayerId(cheatLog.getPlayerId());
			cheatData.setNick(cheatLog.getNick());
			cheatData.setItemId(cheatLog.getItemId());
			cheatData.setItemName(cheatLog.getItemName());
			cheatData.setDelta(cheatLog.getDelta());
			cheatData.setDeltaCheat(cheatLog.isDeltaCheat());
			cheatData.setCurrNum(cheatLog.getCurrNum());
			cheatData.setCurrCheat(cheatLog.isCurrCheat());
			cheatData.setTime(cheatLog.getTime());
			cheatData.setReason(cheatLog.getReason());
			cheatTable.getDatas().add(cheatData);
			batchNum += 1;
			if(!all && batchNum >= 300) {
				break;
			}
			cheatLog = cheatQueue.poll();
		}
		
		backstagePoster.jsonPost(GameApi.cheatReport, cheatTable);
		logger.info("向后台上报作弊数量{}", cheatTable.getDatas().size());
	}
	
	@PostConstruct
	private void console() {
		ConsoleUtil.addFunction("ch", () -> {
			log();
		});
	}
	
	public void log() {
		for(int i = 0; i < 10; i++) {
			CheatLog log = new CheatLog();
			log.setPlayerId(333);
			log.setNick("AAA");
			log.setItemId(111);
			log.setItemName("AAA");
			log.setDelta(1);
			log.setDeltaCheat(true);
			log.setCurrNum(1);
			log.setCurrCheat(false);
			log.setTime(DateTimeUtil.currMillis());
			log.setReason("略");
			this.addCheat(log);
		}
		System.out.println("作弊测试");
	}
}
